﻿#region

using System;
using System.Diagnostics;
using System.Web;

#endregion

namespace HouseHoldBudget.Core.Infrastructure
{
    /// <summary>
    ///   A broker for events from the http application. The purpose of this class is to reduce the risk of temporary errors during initialization causing the site to be crippled.
    /// </summary>
    public class EventBroker
    {
        #region Fields

        public EventHandler<EventArgs> AcquireRequestState;
        public EventHandler<EventArgs> AuthorizeRequest;
        public EventHandler<EventArgs> BeginRequest;
        public EventHandler<EventArgs> EndRequest;
        public EventHandler<EventArgs> Error;
        public EventHandler<EventArgs> PostMapRequestHandler;
        public EventHandler<EventArgs> PostResolveRequestCache;

        #endregion

        #region Constructors

        static EventBroker()
        {
            Instance = new EventBroker();
        }

        #endregion

        #region Instance Methods

        /// <summary>
        ///   Attaches to events from the application instance.
        /// </summary>
        public virtual void Attach(HttpApplication application)
        {
            Trace.WriteLine("EventBroker: Attaching to " + application);

            application.BeginRequest += Application_BeginRequest;
            application.AuthorizeRequest += Application_AuthorizeRequest;

            application.PostResolveRequestCache += Application_PostResolveRequestCache;
            application.PostMapRequestHandler += Application_PostMapRequestHandler;

            application.AcquireRequestState += Application_AcquireRequestState;
            application.Error += Application_Error;
            application.EndRequest += Application_EndRequest;

            application.Disposed += Application_Disposed;
        }

        #endregion

        #region Event Handling

        protected void Application_AcquireRequestState(object sender, EventArgs e)
        {
            if (AcquireRequestState != null)
            {
                Debug.WriteLine("Application_AcquireRequestState");
                AcquireRequestState(sender, e);
            }
        }

        protected void Application_AuthorizeRequest(object sender, EventArgs e)
        {
            if (AuthorizeRequest != null)
            {
                Debug.WriteLine("Application_AuthorizeRequest");
                AuthorizeRequest(sender, e);
            }
        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            if (BeginRequest != null)
            {
                Debug.WriteLine("Application_BeginRequest");
                BeginRequest(sender, e);
            }
        }

        protected void Application_EndRequest(object sender, EventArgs e)
        {
            if (EndRequest != null)
                EndRequest(sender, e);
        }

        protected void Application_Error(object sender, EventArgs e)
        {
            if (Error != null)
                Error(sender, e);
        }

        /// <summary>
        ///   Detaches events from the application instance.
        /// </summary>
        private void Application_Disposed(object sender, EventArgs e)
        {
            Trace.WriteLine("EventBroker: Disposing " + sender);
        }

        private void Application_PostMapRequestHandler(object sender, EventArgs e)
        {
            if (PostMapRequestHandler != null)
            {
                Debug.WriteLine("Application_PostMapRequestHandler");
                PostMapRequestHandler(sender, e);
            }
        }

        private void Application_PostResolveRequestCache(object sender, EventArgs e)
        {
            if (PostResolveRequestCache != null)
            {
                Debug.WriteLine("Application_PostResolveRequestCache");
                PostResolveRequestCache(sender, e);
            }
        }

        #endregion

        #region Class Properties

        /// <summary>
        ///   Accesses the event broker singleton instance.
        /// </summary>
        public static EventBroker Instance
        {
            get
            {
                return Singleton<EventBroker>.Instance;
            }
            protected set
            {
                Singleton<EventBroker>.Instance = value;
            }
        }

        #endregion
    }
}